using System;
using System.Collections.Generic;
using System.Text;
using Mogre;

namespace com.petiteappli.xenocide
{
class ObjectTextDisplay {

    public ObjectTextDisplay(Mogre.MovableObject p, Mogre.Camera c) {
		    m_p = p;
		    m_c = c;
		    m_enabled = false;
		    m_text = "";

		    // create an overlay that we can use for later
            mName = p.Name + "_overlay";
		    m_pOverlay = Mogre.OverlayManager.Singleton.Create(p.Name+"_overlay");
		    m_pContainer = (Mogre.OverlayContainer)Mogre.OverlayManager.Singleton.CreateOverlayElement(
                      "Panel", mName+"_container");

		    m_pOverlay.Add2D(m_pContainer);

            m_pText = Mogre.OverlayManager.Singleton.CreateOverlayElement("TextArea", p.Name + "_overlayText");
		    m_pText.SetDimensions(1.0f, 1.0f);
            m_pText.MetricsMode = GuiMetricsMode.GMM_PIXELS;
		    m_pText.SetPosition(0, 0);

		    m_pText.SetParameter("font_name", "BlueCond");
		    m_pText.SetParameter("char_height", "12");
		    m_pText.SetParameter("horz_align", "center");
            m_pText.Colour = Mogre.ColourValue.White;

		    m_pContainer.AddChild(m_pText);
		    m_pOverlay.Show();
	    }

            ~ObjectTextDisplay() {

                    // overlay cleanup -- Ogre would clean this up at app exit but if your app 
                    // tends to create and delete these objects often it's a good idea to do it here.

		    ///m_pOverlay.Hide();
		    Mogre.OverlayManager overlayManager = Mogre.OverlayManager.Singleton;
            try
            {
                m_pContainer.RemoveChild(mName);
                m_pOverlay.Remove2D(m_pContainer);
                overlayManager.DestroyOverlayElement(m_pText);
                overlayManager.DestroyOverlayElement(m_pContainer);
                overlayManager.Destroy(m_pOverlay);
            }
            catch (Exception e)
            {   
                
            }
		        
            }

        public bool Enabled
        {
            set
            {
                m_enabled = value;
                if (value)
                    m_pOverlay.Show();
                else
                    m_pOverlay.Hide();
            }
        }

	    public String  Text {
            set
            {
                m_text = value;
                m_pText.Caption = value;
            }
            get
            { return m_text; }
	    }

	    

    
	    Mogre.MovableObject m_p;
	    Mogre.Camera m_c;
	    bool m_enabled;
	    Mogre.Overlay m_pOverlay;
	    Mogre.OverlayElement m_pText;
	    Mogre.OverlayContainer m_pContainer;
	    String m_text;
        String mName;
    

    public void update()  {
	    if (!m_enabled)
		    return;

	    // get the projection of the object's AABB into screen space
	    AxisAlignedBox bbox = m_p.GetWorldBoundingBox(true);
	    Mogre.Matrix4 mat = m_c.GetViewMatrix(true);

	    Vector3[] corners = bbox.GetAllCorners();

	    float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f;

            // expand the screen-space bounding-box so that it completely encloses 
            // the object's AABB
	    for (int i=0; i<8; i++) {
		    Mogre.Vector3 corner = corners[i];

                    // multiply the AABB corner vertex by the view matrix to 
                    // get a camera-space vertex
		    corner = mat * corner;

                    // make 2D relative/normalized coords from the view-space vertex
                    // by dividing out the Z (depth) factor -- this is an approximation
		    float x = corner.x / corner.z + 0.5f;
		    float y = corner.y / corner.z + 0.5f;

		    if (x < min_x) 
			    min_x = x;

		    if (x > max_x) 
			    max_x = x;

		    if (y < min_y) 
			    min_y = y;

		    if (y > max_y) 
			    max_y = y;
	    }

	    // we now have relative screen-space coords for the object's bounding box; here
	    // we need to center the text above the BB on the top edge. The line that defines
	    // this top edge is (min_x, min_y) to (max_x, min_y)

	    m_pContainer.SetPosition(1.0f-max_x, min_y);
	    //m_pContainer.SetPosition(1.0f-max_x, min_y);  // Edited by alberts: This code works for me
	    m_pContainer.SetDimensions(max_x - min_x, 0.1f); // 0.1, just "because"
    }
}
}
